#include <JXQCore/JList>
#include <JXQCore/JString>
#include <JXQCore/JDebug>
#include <vector>

using namespace std;
using namespace JXQ;

struct Test
{
	Test(const JString &str) : str(str) {}
	JString str;
	int64_t a, b, c, d, e, f, g, h, i, j, k, l, m, n;
	int64_t o, p, q, r, s, t, u, v , w, x, y, z;
};
typedef JList<Test>  TestList;

#define JLIST_TEST

#ifdef JLIST_TEST
static void JList_test();
#else
static void std_vector_test();
#endif

int main(int argc, char *argv[])
{
	J_UNUSED(argc);
	J_UNUSED(argv);

#ifdef JLIST_TEST
	JList_test();
#else
	std_vector_test();
#endif

	return 0;
}

#ifdef JLIST_TEST
static void JList_test()
{
	TestList list1;
	for(int i=0; i<10; i++)
	{
		list1 << Test(JString("ha_%1").arg(i));
		jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();
	}
	for(auto &i : list1)
		jDebug() << "value1 =" << i.str;


	jDebug() << "";


	auto list2 = list1;
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	TestList list3 = {Test("hello"), Test("world"), Test("你好"), Test("世界")};
	jDebug() << "size3 =" << list3.size() << ", capacity3 =" << list3.capacity();
	for(auto &i : list3)
		jDebug() << "value3 =" << i.str;


	jDebug() << "";


	list2 = list3;
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	for(int i=0; i<3; i++)
		list2.insert(3-i, Test(JString("ii_%1").arg(i)));
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	for(auto &i : list2)
		i.str = "----------";
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	for(int i=0; i<3; i++)
		list1.erase(0);
	jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();
	for(auto &i : list1)
		jDebug() << "value1 =" << i.str;


	jDebug() << "";


	auto it = list1.begin();
	while( it != list1.end() )
		it = list1.erase(it);
	jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();

	for(int i=0; i<20; i++)
		list3.insert(0, Test(JString("ha_%1").arg(i)));
	for(auto &i : list3)
		jDebug() << "value3 =" << i.str;

	for(int i=0; i<50000; i++)
		list3.emplaceFront(JString("ha_%1").arg(i));
}
#else
static void std_vector_test()
{
	vector<Test> list1;
	for(int i=0; i<10; i++)
	{
		list1.emplace_back(Test(JString("ha_%1").arg(i)));
		jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();
	}
	for(auto &i : list1)
		jDebug() << "value1 =" << i.str;


	jDebug() << "";


	auto list2 = list1;
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	vector<Test> list3 = {Test("hello"), Test("world"), Test("你好"), Test("世界")};
	jDebug() << "size3 =" << list3.size() << ", capacity3 =" << list3.capacity();
	for(auto &i : list3)
		jDebug() << "value3 =" << i.str;


	jDebug() << "";


	list2 = list3;
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	auto it = list2.begin();
	for(int i=0; i<3; i++)
	{
		++it;
		list2.insert(it, Test(JString("ii_%1").arg(i)));
	}
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	for(auto &i : list2)
		i.str = "----------";
	jDebug() << "size2 =" << list2.size() << ", capacity2 =" << list2.capacity();
	for(auto &i : list2)
		jDebug() << "value2 =" << i.str;


	jDebug() << "";


	for(int i=0; i<3; i++)
		list1.erase(list1.begin());
	jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();
	for(auto &i : list1)
		jDebug() << "value1 =" << i.str;


	jDebug() << "";


	it = list1.begin();
	while( it != list1.end() )
		it = list1.erase(it);
	jDebug() << "size1 =" << list1.size() << ", capacity1 =" << list1.capacity();

	for(int i=0; i<20; i++)
		list3.emplace(list3.begin(), JString("ha_%1").arg(i));
	for(auto &i : list3)
		jDebug() << "value3 =" << i.str;

	for(int i=0; i<20000; i++)
		list3.emplace(list3.begin(), JString("ha_%1").arg(i));
}
#endif
